package msg

import (
	"errors"
	"strings"

	"google.golang.org/protobuf/reflect/protoreflect"
)

// msgCode --> msgDesc 字典
var msgCodeAndMsgDescMap = make(map[int32]protoreflect.MessageDescriptor)

// msgName --> msgCode 字典
var msgNameAndMsgCodeMap = make(map[string]int32)

// 初始化
func init() {
	init2Map(E_MsgCode_Login_value, File_LoginMsgProtocol_proto.Messages())
	init2Map(E_MsgCode_Game_value, File_GameMsgProtocol_proto.Messages())
}

// 根据消息代号获取消息描述
func getMsgDescByMsgCode(msgCode int32) (protoreflect.MessageDescriptor, error) {
	if msgCode < 0 {
		return nil, errors.New("消息代码无效")
	}

	return msgCodeAndMsgDescMap[msgCode], nil
}

// 根据消息名称获取消息代号
func getMsgCodeByMsgName(msgName string) (int32, error) {
	if len(msgName) <= 0 {
		return -1, errors.New("消息名称为空")
	}

	return msgNameAndMsgCodeMap[msgName], nil
}

// 初始化两个字典,
// msgCode --> msgDesc 字典 & msgName --> msgCode 字典
func init2Map(msgCodeMap map[string]int32, msgDescList protoreflect.MessageDescriptors) {
	if len(msgCodeMap) <= 0 ||
		nil == msgDescList ||
		msgDescList.Len() <= 0 {
		return
	}

	var tempMap = make(map[string]int32)

	for k, v := range msgCodeMap {
		// 清除下划线 & 全部转为小写
		// 例如: USER_LOGIN_CMD ==> userlogincmd
		msgId := strings.ToLower(
			strings.Replace(k, "_", "", -1),
		)

		tempMap[msgId] = v
	}

	for i := 0; i < msgDescList.Len(); i++ {
		msgDesc := msgDescList.Get(i)
		// 获得消息名称之后, 也把消息名称清除下划线 & 全部转为小写
		// 例如: UserLoginCmd ==> userlogincmd
		msgName := string(msgDesc.Name())
		msgId := strings.ToLower(
			strings.Replace(msgName, "_", "", -1),
		)

		msgCode := tempMap[msgId]

		msgNameAndMsgCodeMap[msgName] = msgCode
		msgCodeAndMsgDescMap[msgCode] = msgDesc
	}
}
